搭建sftp,并使用Python上传文件

查看openssh的版本

1
ssh -V

使用ssh -V 命令来查看openssh的版本,版本必须大于4.8p1,低于的这个版本需要升级。

创建sftp组

1
groupadd sftp

创建sftp组

创建sftp用户

1
2
useradd -g sftp -s /bin/false mysftp  
passwd mysftp

创建一个sftp用户,用户名为mysftp,密码为mysftp
修改用户密码和修改Linux用户密码是一样的。

修改sftp组用户的家目录,指定文件上传文件夹

1
2
mkdir -p /data/sftp/mysftp  
usermod -d /data/sftp/mysftp mysftp

sftp组的用户的home目录统一指定到/data/sftp下,按用户名区分,这里先新建一个mysftp目录,然后指定mysftp的home为/data/sftp/mysftp

配置sshd_config

配置sshd_config,文本编辑器打开 /etc/ssh/sshd_config vi /etc/ssh/sshd_config找到如下这行,用#符号注释掉,大致在文件末尾处。

1
#Subsystem      sftp    /usr/libexec/openssh/sftp-server

在文件最后面添加如下几行内容,然后保存。

1
2
3
4
5
6
Subsystem       sftp    internal-sftp    
Match Group sftp
ChrootDirectory /data/sftp/%u
ForceCommand internal-sftp
AllowTcpForwarding no
X11Forwarding no

设置权限

1
2
3
4
5
6
chown root:sftp /data/sftp/mysftp  
chmod 755 /data/sftp/mysftp

mkdir /data/sftp/mysftp/upload
chown mysftp:sftp /data/sftp/mysftp/upload
chmod 755 /data/sftp/mysftp/upload

selinux设置

修改/etc/selinux/config,文本编辑器打开/etc/selinux/config

1
vi /etc/selinux/config

将文件中的SELINUX=enforcing 修改为 SELINUX=disabled ,然后保存。在输入命令

重启sshd

1
service sshd restart

使用Python代码上传

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# !/usr/bin/python
# coding=utf-8
import datetime
import paramiko
import os
import sys
import settings

if __name__ == '__main__':
sys.path.insert(0, os.path.abspath(os.curdir))


class SFTP(object):
def __init__(self):
self.host = settings.SFTP_HOST
self.port = settings.SFTP_PORT
self.username = settings.SFTP_USERNAME
self.password = settings.SFTP_PASSWORD
sf = None
try:
sf = paramiko.Transport((self.host, self.port))
sf.connect(username=self.username, password=self.password)
except Exception, e:
print "Server Connect Error"
self.sf = sf

def sftp_upload(self, local_path, remote_path, local_csv_name):
if self.sf:
try:
sftp = paramiko.SFTPClient.from_transport(self.sf)
# 判断文件是否存在,不存在则创建
local_csv_file_path = os.path.join(local_path, local_csv_name + '.csv')
if not os.path.exists(local_csv_file_path):
open(local_csv_file_path, 'a')
sftp.put(local_csv_file_path, os.path.join(remote_path, local_csv_name + '.csv'))
# 状态标识文件,有done则表示文件上传完成
local_done_file_path = os.path.join(local_path, local_csv_name + '.done')
if not os.path.exists(local_done_file_path):
open(local_done_file_path, 'a')
sftp.put(local_done_file_path, os.path.join(remote_path, local_csv_name + '.done'))
except Exception, e:
print 'upload exception:', e
finally:
self.sf.close()

if __name__ == '__main__':
yesterday = datetime.datetime.today() - datetime.timedelta(days=1)
local_path = os.path.join(settings.DATA_FILE_PATH, 'LppzData')
remote_path = '/upload/'
local_path = os.path.join(settings.DATA_FILE_PATH, 'LppzData')
# 测试文件
# local_csv_name = "test1"
local_csv_name = 'LppzData_' + yesterday.strftime('%Y%m%d')
obj = SFTP()
obj.sftp_upload(local_path, remote_path, local_csv_name)

问题

fatal: bad ownership or modes for chroot directory “/data/sftp/wmt_sftp”
在工作中出现几次登录不上的情况,查看/var/log/securt下的日志发现出现上面的错误。这是因为文件夹的权限不对导致登录不上。